package com.lrd.snapshotorder.config.datasource.shardingalgorithm;

import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.MultipleKeysDatabaseShardingAlgorithm;
import com.lrd.snapshotorder.util.ShardingIdUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.LinkedHashSet;

/**
 * 分库
 * MultipleKeysDatabaseShardingAlgorithm 是一种多键分库算法，用于将多个键值对数据分散到不同的数据库中。这种算法适用于那些需要根据多个关键字进行查询的应用。
 * 该算法的基本思想是将输入的多个键值对数据根据某种规则划分到不同的数据库中。通常情况下，该规则会考虑键值对的某些属性，比如键的哈希值或者某个属性的取值范围等。通过这种方式，可以确保相同键值对的数据被划分到同一个数据库中，从而保证了查询的一致性。
 * ComplexKeysShardingAlgorithm 是一种复杂键分表算法，用于将具有复杂结构的键值对数据划分到不同的数据表中。这种算法适用于那些具有复杂数据结构的应用，比如关系型数据库中的关联表。
 * 该算法的基本思想是根据键的某些属性将输入的键值对数据划分到不同的数据表中。通常情况下，该属性会是一个关键字段，比如一个与主键相关联的外键。通过这种方式，可以确保具有相同属性值的数据被划分到同一个数据表中，从而减少了数据的查询和维护的复杂性。
 * 总的来说，多键分库算法适用于那些需要根据多个关键字进行查询的应用，而复杂键分表算法适用于那些具有复杂数据结构的应用。这两种算法都可以帮助我们实现数据的分库分表，从而提高应用的性能和可扩展性。
 */
@Slf4j
public class MultipleKeysShardingDatabase implements MultipleKeysDatabaseShardingAlgorithm {

    private static final int DB_COUNT = 2;

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, Collection<ShardingValue<?>> shardingValues) {
        Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
        for (ShardingValue<?> value : shardingValues) {
            for (String dbName : availableTargetNames) {
                String str = value.getValue() + "";
                long index = Long.parseLong(ShardingIdUtils.getFirstNumber(ShardingIdUtils.getFirstNumber(str, 6), 2));
                if (dbName.endsWith(index % DB_COUNT + "")) {
                    log.info("=================DB rule route:{}", dbName);
                    result.add(dbName);
                    return result;
                }
            }
        }
        return result;
    }
}
